//SVG Adapter namespace
squigle.svgAdapter = {};

/**
 * Value Objects
 */
squigle.svgAdapter.Point = function(x, y){    
    this.x = function(){
        return x || 0;
    };
    
    this.y = function(){
        return y || 0;
    }
};

squigle.svgAdapter.Size = function(width, height){
    this.width = function(){
        return width;  
    };
    
    this.height = function(){
        return height;
    };
};

/**
 * Entities
 */ 
squigle.svgAdapter.Canvas = function(size, coordSize, coordOrigin){
    
    var _pixelResolution = (function(){
        var coordDiameter = (coordSize.width() > coordSize.height()) ? coordSize.width() : coordSize.height();
        var canvasDiamter = (size.width() > size.height()) ? size.width() : size.height();
        return coordDiameter / canvasDiamter;
    })();
    
    var _container = document.createElement("div");
    _container.style.width = size.width() + "px";
    _container.style.height = size.height() + "px";
    
    //With SVG the width and height are always the same as the biggest value
    var _canvasDiameter = (coordSize.width() > coordSize.height()) ? coordSize.width() : coordSize.height();    
    
    var _node = document.createElementNS("http://www.w3.org/2000/svg", "svg:svg");
    _node.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
    _node.setAttribute("width", size.width() + "px");
    _node.setAttribute("height", size.height() + "px");
    _node.setAttribute("viewBox", [coordOrigin.x(), coordOrigin.y(), coordSize.width(), coordSize.height()].join(" "));
    _node.setAttribute("preserveAspectRatio", "none");
    _container.appendChild(_node);
    
    this.container = function(){
        return _container;    
    };
    
    this.append = function(shape){
        //alert(shape.stroke().size() +" "+ Math.round(shape.stroke().size() * _pixelResolution));
        _node.setAttribute("stroke-width", Math.round(shape.stroke().size() * _pixelResolution) + "px");
        _node.appendChild(shape.node());
    };
    
    this.node = function(){
        return _node;    
    };
    
    this.scale = function(resolution){
        _container.style.width = parseInt(_container.style.width) * resolution + "px";
        _container.style.height = parseInt(_container.style.height) * resolution + "px";        
        _node.setAttribute("width", parseInt(_node.style.width) * resolution + "px" );
        _node.setAttribute("height", parseInt(_node.style.height) * resolution + "px");        
    };    
};

squigle.svgAdapter.Rectangle = function(size, point, stroke, fill){
    var _node = (
        function(){
            //Node
            var node = document.createElementNS("http://www.w3.org/2000/svg", "rect");
            point = point || new squigle.Point();
            node.setAttribute("width", size.width() + "px");
            node.setAttribute("height", size.height() + "px");
            node.setAttribute("x", point.x() + "px");
            node.setAttribute("y", point.y() + "px");
            
            //Stroke / Fill
            stroke = stroke || new squigle.Stroke();
            fill = fill || new squigle.Fill();            
            node.setAttribute("stroke-width", stroke.size() + "px");
            node.setAttribute("stroke", stroke.color());
            node.setAttribute("stroke-opacity", stroke.opacity() / 100);
            node.setAttribute("fill", fill.color());
            node.setAttribute("fill-opacity", fill.opacity() / 100); 
            return node;
        }
    )();
    
    this.node = function(){
        return _node;  
    };
    
    this.stroke = function(){
        return stroke;  
    };
};

squigle.svgAdapter.Path = function(stroke, fill){
    var _path = "";
    
    var _node = (
        function(){
            //Node
            var node = document.createElementNS("http://www.w3.org/2000/svg", "path");
            node.setAttribute("d", _path);
            
            //Stroke / Fill
            stroke = stroke || new squigle.Stroke();
            fill = fill || new squigle.Fill();               
            
            var _endcap = (stroke.endcap() == "flat") ? "butt" : stroke.endcap();
            
            var _dasharray = {
                solid:				"none",
                shortdash:			[3, 1],
                shortdot:			[1, 1],
                shortdashdot:		[3, 1, 1, 1],
                shortdashdotdot:	[3, 1, 1, 1, 1, 1],
                dot:				[1, 3],
                dash:				[4, 3],
                longdash:			[8, 3],
                dashdot:			[4, 3, 1, 3],
                longdashdot:		[8, 3, 1, 3],
                longdashdotdot:		[8, 3, 1, 3, 1, 3]
            };

            var _dash = _dasharray[stroke.dash()];
            
            if(_dash instanceof Array){
                for(var i = 0; i < _dash.length; i++){
                    _dash[i] *= stroke.size();
                }
                if(_endcap != "butt"){
                    for(var i = 0; i < _dash.length; i += 2){
                        _dash[i] -= stroke.size();
                        if(_dash[i] < 1){ _dash[i] = 1; }
                    }
                    for(var i = 1; i < _dash.length; i += 2){
                        _dash[i] += stroke.size();
                    }
                }
                _dash = _dash.join(",");                  
            }
            
            node.setAttribute("stroke", stroke.color());
            node.setAttribute("stroke-opacity", stroke.opacity() / 100);
            node.setAttribute("stroke-linecap", _endcap);
            node.setAttribute("stroke-linejoin", stroke.linejoin());
            node.setAttribute("stroke-dasharray", _dash);
            node.setAttribute("fill", fill.color());
            node.setAttribute("fill-opacity", fill.opacity() / 100); 
            return node;
        }
    )();
    
    this.node = function(){
        return _node;  
    };
    
    this.stroke = function(){
        return stroke;  
    };    
    
    this.moveTo = function(point, relative){
        var letter = (relative) ? "m" : "M";
        _path += " " + letter + " " + point.x() + "," + point.y();
        _node.setAttribute("d", _path);
    };
    
    this.lineTo = function(point, relative){
        var letter = (relative) ? "l" : "L";
        _path += " " + letter + " " + point.x() + "," + point.y();
        _node.setAttribute("d", _path);      
    };
    
    this.curveTo = function(controlPoint1, controlPoint2, endPoint, relative){
         var letter = (relative) ? "c" : "C";
        _path += " " + letter + " " + controlPoint1.x() + "," + controlPoint1.y() + " " + controlPoint2.x() + "," + controlPoint2.y() + " " + endPoint.x() + "," + endPoint.y();
        _node.setAttribute("d", _path);  
    };
    
    this.close = function(){
        _path += " Z";
        _node.setAttribute("d", _path); 
    };
    
    this.clear = function(){};    
};